1. /* sdfrqrrt.cpp by K.Tsuru */
  2. // function ID = 3013 DRADIX only
  3. #include "sn.h"
  4. static const char* const func = "Qrrt/RecQrrt";
  5. /*****************************************************************
  6. SDouble class
  7. reciprocal quartic root of x
  8. [Algorithm]
  9. Get a solusion of an equation 1/(x^4) - a = 0 by the
  10. Newton's method with "doubling effective figures"(DEF).
  11. See Sqrt() for detail.
  12. Let d(n) = x(n){1-a*x(n)^4}/4... faster than {x(n)-a*x(n)^5}/4
  13. because 1-a*x(n)^4 is very small
  14. x(n+1) = x(n) + d(n)
  15. ******************************************************************/
  16. SDouble RecQrrt(const SDouble& a){
  17. if(a.Type() != a.REAL) a.SetError(a.RADIX_ERR, func, 3013);
  18. if(a.Sign() <= 0) a.SetError(a.DOMAIN_ERR, func, 3013);
  19. RealSize C;
  20. uint max_sz = a.MaxSize();
  21. SDouble w(Dabs(a)), one(1.0);
  22. double w0;
  23. if(a.IsOne()) return one; // a = 1.0
  24. int e = w.NetRdxExp(), q, r, pow10 = 0;
  25. // a = d*R^e = (d*R^q)*R^(4*r) , e = q + 4r
  26. r = e/4;
  27. q = 4*r;
  28. if(e - q > 0){ r++; q += 4; }
  29. w.MultPowRdx(-q); // Here 1/R^4 <= w < 1.0.
  30. /*set an initial value y0*/
  31. w0 = doubleD(w);
  32. while(w0 < 1.0e-4){ // 0.0001 <= w0 < 1.0
  33. w0 *= 10000.0; pow10++;
  34. }
  35. if(pow10) w.MultPow10(4*pow10);
  36. //enter the irreducible size mode
  37. SDouble y(a.REAL, max_sz), delta(a.REAL, max_sz), z(a.REAL, max_sz);
  38. y = pow(w0, -1.0/4.0); // y has about DOUBLE_FIG figures.
  39. /***************************************************************/
  40. int c = 0, itrmax = howpow2( (DFIGURES*max_sz)/DOUBLE_FIG+1 ) +6;
  41. uint ef = (DOUBLE_FIG*2u)/DFIGURES, fig = C.EffFigures();
  42. int fullPrec = 0;
  43. delta = w0 - w;
  44. if( delta.Sign() ){
  45. // If w0 is very close to double value, higher precision is necessary.
  46. ef = max( ef, 2u*(uint)abs( delta.NetRdxExp()) );
  47. }
  48. //enter fiexd point mode
  49. y.FixedPoint(y.RdxExp());
  50. if(ef > fig) ef = fig;
  51. do{
  52. if( (ef = C.SetEffFig(ef)) >= fig) fullPrec = 1;
  53. z = y*y; z = z*z; // z = y^4
  54. delta = y*(one - w*z);
  55. delta = DsDiv(delta, 4); // delta /= 4
  56. y += delta;
  57. c++;
  58. ef *= 2;
  59. if(ef >= fig) ef = fig;
  60. C.SetEffFig(0);
  61. } while( ( !delta.IsHidden() && (c < itrmax) ) || !fullPrec );
  62. y.iterationCount = c;
  63. //#ifndef NDEBUG
  64. if(c == itrmax) y.SetError(y.FATAL, func, 3012);
  65. //#endif
  66. y.PointFree();
  67. y.Reform(3011);
  68. if(y.Verify()){
  69. z = y*y; z = z*z; // z =y^4
  70. delta = one - z*w; // delta = 1 - w*y^4
  71. if(!delta.IsMLT(w)){
  72. y.SetError(y.VERIFY, func, 3010);
  73. }
  74. }
  75. if(r) y.MultPowRdx(-r);
  76. if(pow10) y.MultPow10(pow10);
  77. return y;
  78. }

sdfrqrrt.cpp : last modifiled at 2000/12/07 10:39:40(2,537 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).